package com.phb.puhuibao.web.controller;

 
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.Random;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.idap.clinic.entity.UploadFile;
import com.idp.pub.constants.Constants;
import com.idp.pub.service.IBaseService;
import com.idp.pub.web.controller.BaseController;
import com.phb.puhuibao.entity.BorrowerManagement;
import com.phb.puhuibao.entity.CreditMatching;
import com.phb.puhuibao.entity.MobileUser;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;  
import java.io.FileNotFoundException;
import java.io.FileOutputStream;  
import java.io.InputStream;  
import java.io.OutputStream;  
  




import javax.servlet.ServletException;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse; 
 

@Controller
@RequestMapping(value = "/creditMatching")
public class CreditMatchingController extends BaseController<CreditMatching, String> {
	
	public int num = 7;
	
	@Resource(name = "creditMatchingService")
	public void setBaseService(IBaseService<CreditMatching, String> baseService) {
		super.setBaseService(baseService);
	}
	
	@javax.annotation.Resource(name = "borrowerManagementService")
	private IBaseService<BorrowerManagement, String> borrowerService;
	
	@javax.annotation.Resource(name = "jdbcTemplate")
	private JdbcTemplate jdbcTemplate;
	
	
	
	// min 到 max 之间的n个不同的随机数
	public   int[] randomCommon(int min, int max, int n){  
	    if (n > (max - min + 1) || max < min) {  
	           return null;  
	       }  
	    int[] result = new int[n];  
	    int count = 0;  
	    while(count < n) {  
	        int num = (int) (Math.random() * (max - min)) + min;  
	        boolean flag = true;  
	        for (int j = 0; j < n; j++) {  
	            if(num == result[j]){  
	                flag = false;  
	                break;  
	            }  
	        }  
	        if(flag){  
	            result[count] = num;  
	            count++;  
	        }  
	    }  
	    return result;  
	}  
	
	
	public  int getnewradom(int sum,int count){
		Random rdm=new Random();
		int temp = rdm.nextInt()%sum;
		double persent= sum/(count-1);
		double minpersent= sum/((count-1)*2);
		while(temp > persent ||  temp < minpersent){
			//temp = rdm.nextInt(sum);
			temp = (int) Math.round(Math.random()*100);
		}
		 return temp;
	}
	// 总和为 sum 的count个随机数
	public List<Integer> GetResult(int sum, int count)
    {
		Random rdm=new Random();
        List<Integer> result = new ArrayList<Integer>(count);
        int last =sum;
        for(int i=0;i<count-1;i++){
        	int temp = getnewradom(sum,count);
        	last = last - temp;
        	result.add(temp);
        }
        
        result.add(last);
		if(last<=0){
			return null;
		}   
      
        return result;
    }
	
	private  Date getLastDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, -1);
        return cal.getTime();
    }
	
	private String getBatchname () {
		
		Date date = new Date();
        String batchName="";

		 SimpleDateFormat df=new SimpleDateFormat("yyyyMMdd");
		 SimpleDateFormat df1=new SimpleDateFormat("yyyyMM");
		 
		 String nowdate= df.format(date); 
		 String nowmonth= df1.format(date); 
	     String lastmonth =   df1.format(getLastDate(date)) ;
	     
	     String last25 = lastmonth+"25";
		 String this10 = nowmonth+"10";
		 String this25 = nowmonth+"25";
 
		 Date todaydate;
		 Date last25d ;
		 Date this10d;
		 Date this25d ;
		try {
			 todaydate = df.parse(nowdate);
			 last25d =    df.parse(last25);
			 this10d =    df.parse(this10);
			 this25d =    df.parse(this25);
			 
	         if(todaydate.after(this10d) && this25d.after(todaydate) || todaydate.equals(this25d)){//如果现在的时间是在这个月的10号和25号之间,包含15号
	         	batchName = nowmonth+"-02";
	          }else  if(todaydate.after(last25d) && this10d.after(todaydate) || todaydate.equals(this10d)){// 如果现在是本月10号（包含）和上月25号之间 
	         	batchName = nowmonth+"-01";
	          }else{
	         	 batchName = ""; 
	          }
		} catch (ParseException e) {
			 batchName = ""; 
		}
 
 
         return batchName;
         
    }
	
	private  List<CreditMatching> getRatio(List<BorrowerManagement> doinglist, double sum,String batchName){
		
		List<CreditMatching> newlist = new ArrayList<CreditMatching>();
		
		 double smallmountsum=0.0;
		    double smallmountper=0.0;
		    int smallnum = 0;
		    DecimalFormat ddf = new DecimalFormat("#.00");  
         
         
		    for(int i=0;i<num;i++){
		    	BorrowerManagement bb = doinglist.get(i);
		    	if((bb.getContractAmount()-bb.getFilledAmount())<=100000){//小额的先满足   小于10万的，称为小额，都一次性满足
		    		smallnum++; // 小额合同个数
		    		smallmountsum+=bb.getContractAmount()-bb.getFilledAmount();//小额合同总金额
		    		//smallmountper+=(bb.getContractAmount()-bb.getFilledAmount())/sum;

		    		CreditMatching cm = new CreditMatching();
		    		cm.setBorrowId(bb.getRecordId());
		    		cm.setBatchName(batchName);
			    	cm.setBorrowerName(bb.getBorrowerName());
			    	//cm.setBorrowPersentage( Double.valueOf(ddf.format( (bb.getContractAmount()-bb.getFilledAmount())/sum)));
			    	cm.setBorrowPersentage((bb.getContractAmount()-bb.getFilledAmount())/sum); //数据库里存的是高精度小数
			    	cm.setBorrowAmount(bb.getContractAmount()-bb.getFilledAmount());//现有债权
			    	cm.setBorrowLeft(0);//一次性满足
			    	newlist.add(cm);
		    		//bb.getContractAmount()-bb.getFilledAmount()-newpersents.get(i)/100.0*sum
		    	}

		    }
		    
		    //List<Integer> newpersents =  GetResult(100-(int)Math.round(smallmountper*100),num-smallnum);//形成剩余的百分比的随机分配
		    List<Integer> newpersents =  GetResult(100,num-smallnum);//分完小额用户后，剩余的钱按照随机比例分配 
		    int j=0;
		    for(int i=0;i<num;i++){
		      
		    	BorrowerManagement bb = doinglist.get(i);
		    	if((bb.getContractAmount()-bb.getFilledAmount())>100000){//剩余的都是大额
		    		 
                    double temppersentage=(newpersents.get(j)/100.0*(sum-smallmountsum))/sum;
                    double tempamount = newpersents.get(j++)/100.0*(sum-smallmountsum);
		    		CreditMatching cm = new CreditMatching();
		    		cm.setBorrowId(bb.getRecordId());
		    		cm.setBatchName(batchName);
			    	cm.setBorrowerName(bb.getBorrowerName());
			    	cm.setBorrowPersentage(temppersentage);
			    	cm.setBorrowAmount(bb.getContractAmount()-bb.getFilledAmount());
			    	cm.setBorrowLeft(bb.getContractAmount()-bb.getFilledAmount()-tempamount);
			    	newlist.add(cm);
		    		 
		    	}

		    }
		    
		    return newlist;
		
	}
	
	/**
	 * 获得分配方案
 
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="getRatio")
	@ResponseBody
	public  Map<String, Object> getRatio(@RequestParam double sum ) throws Exception {
	 
		Map<String, Object> data = new HashMap<String, Object>();
		Map<String,Object> params = new HashMap<String,Object>();
		Date date = new Date();
        String batchName="";

		 SimpleDateFormat df=new SimpleDateFormat("yyyyMMdd");
		 SimpleDateFormat df1=new SimpleDateFormat("yyyyMM");
		 
		 String nowdate= df.format(date); 
		 String nowmonth= df1.format(date); 
	     String lastmonth =   df1.format(getLastDate(date)) ;
	     
	     String last25 = lastmonth+"25";
		 String this10 = nowmonth+"10";
		 String this25 = nowmonth+"25";
 
		 Date todaydate =  df.parse(nowdate);
		 Date last25d =    df.parse(last25);
		 Date this10d =    df.parse(this10);
		 Date this25d =    df.parse(this25);
		 
         if(todaydate.after(this10d) && this25d.after(todaydate) || todaydate.equals(this25d)){//如果现在的时间是在这个月的10号和25号之间,包含15号
        	batchName = nowmonth+"-02";
         }else  if(todaydate.after(last25d) && this10d.after(todaydate) || todaydate.equals(this10d)){// 如果现在是本月10号（包含）和上月25号之间 
        	batchName = nowmonth+"-01";
         }else{
 			data.put("result", null);
 			data.put("message", "不能在今天产生债权分配方案，改天再试！");
 			data.put("status", 0);
 			return data;	
 
         }
		 
		
		
		params.put("batchName", batchName);
		 
		List<CreditMatching> cmlist = this.getBaseService().findList(params);
		if(cmlist.size()==0){//需要新生成
			
			params = new HashMap<String,Object>();
			params.put("filledFinished", 1);//0：没有任何分配  1：分配中2： 分配完成
			params.put("orderBy", "filled_pct");
			params.put("order", "desc");
			List <BorrowerManagement>doinglist = borrowerService.findList(params);//分配到一半
			 
			int doingnum=0;
			 for(BorrowerManagement bm:doinglist){
				 if(bm.getFilledPct()>0){
					 doingnum++;
				 }
			 }
			int   leftnum = num-doingnum;//没有分配的人的数目
			
			params = new HashMap<String,Object>();
			params.put("filledFinished", 0);//还没有分配
			 
			List <BorrowerManagement> todolist = borrowerService.findList(params);//还没有任何分配的人
			int todonum = todolist.size();
			
			
		    int [] randomnum = randomCommon(0,todonum-1,leftnum);// 从没有分配的人中随机选择 leftnum个人进行分配
		    
		    for(int i =0;i<randomnum.length;i++){
		    	doinglist.add(todolist.get(randomnum[i]));// 本次选人结束
		    }
		    
		    int ok=0;
		    List<CreditMatching> newlist = getRatio(doinglist,sum,batchName);
 
			data.put("result", newlist);
			data.put("message", "成功产生新的分配方案！");
			data.put("status", 1);
			return data;	
			
		}else{//已经生成，提醒
			data.put("result", null);
			data.put("message", "本周期债权分配方案已经生成过了。");
			data.put("status", 2);
			return data;	
			
		}
		
		
 

		
	}
	
	
	/**
	 * 保存分配方案
 
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="saveRatio")
	@ResponseBody
	public  Map<String, Object> saveRatio( 
			@RequestParam int      borrowId,
			@RequestParam String  borrowerName,
			@RequestParam double   borrowPersentage,
			@RequestParam double      borrowAmount,
			@RequestParam double      borrowLeft,
			@RequestParam String   batchName
			) throws Exception {
 
	 
		Map<String, Object> data = new HashMap<String, Object>();
		Map<String,Object> params = new HashMap<String,Object>();
		
	 
		params.put("batchName", batchName);
		 
		List<CreditMatching> cmlist = this.getBaseService().findList(params);
		
		CreditMatching cm = new CreditMatching();
		cm.setBatchName(batchName);
		cm.setBorrowAmount(borrowAmount);
		cm.setBorrowerName(borrowerName);
		cm.setBorrowId(borrowId);
		cm.setBorrowLeft(borrowLeft);
		cm.setBorrowPersentage(borrowPersentage);
		
		 this.getBaseService().save(cm);
		
		 
  
			 
			data.put("message", "成功保存新的分配方案！");
			data.put("status", 1);
			return data;	
			
		 
	}
	
	
 
	
	
    @ResponseBody
    @RequestMapping(value = "/downloadZip")
    public void downloadZip(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        String fileName =  "12700153file.zip"; 
        /*
         * 限制只有upload和download文件夹里的文件可以下载
         */
        String folderName = "reports";
        
        String fileAbsolutePath = request.getSession().getServletContext()
                .getRealPath("/")
                + "/WEB-INF/" + folderName + "/" + fileName;
        
        
         downloadFile(request, response, fileAbsolutePath);
         
    }
    
    public static void downloadFile(HttpServletRequest request,
            HttpServletResponse response, String filePath, String fileName)
            throws IOException {
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
     
        bis = new BufferedInputStream(new FileInputStream(filePath));
        bos = new BufferedOutputStream(response.getOutputStream());
     
        long fileLength = new File(filePath).length();
     
        response.setCharacterEncoding("UTF-8");
        response.setContentType("multipart/form-data");
        /*
         * 解决各浏览器的中文乱码问题
         */
        String userAgent = request.getHeader("User-Agent");
        byte[] bytes = userAgent.contains("MSIE") ? fileName.getBytes()
                : fileName.getBytes("UTF-8"); // fileName.getBytes("UTF-8")处理safari的乱码问题
        fileName = new String(bytes, "ISO-8859-1"); // 各浏览器基本都支持ISO编码
        response.setHeader("Content-disposition",
                String.format("attachment; filename=\"%s\"", fileName));
     
        response.setHeader("Content-Length", String.valueOf(fileLength));
        byte[] buff = new byte[2048];
        int bytesRead;
        while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
            bos.write(buff, 0, bytesRead);
        }
        bis.close();
        bos.close();
     
    }
     
    /**
     * 下载文件时不指定下载文件名称
     * 
     * @param request
     *            HttpServletRequest
     * @param response
     *            HttpServletResponse
     * @param filePath
     *            文件全路径
     * @throws IOException
     */
    public static void downloadFile(HttpServletRequest request,
            HttpServletResponse response, String filePath) throws IOException {
        File file = new File(filePath);
        downloadFile(request, response, filePath, file.getName());
    }
	
	
}
